﻿/*  CLR版本: 4.0.30319.18063
 * 系统时间: 2014/10/31 14:20:43
 * 创建年份: 2014
 *     作者: 程炜.Snail
 */
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;

namespace Quick.Communicator
{
    /// <summary>
    /// TCP Server
    /// </summary>
    public class UDPServer
    {
        #region 属性
        /// <summary>
        /// 允许连接的最大客户端数量
        /// </summary>
        private int m_MaxConnectionsCount;   // the maximum number of connections the sample is designed to handle simultaneously 
        /// <summary>
        /// Socket I/O缓冲区大小
        /// </summary>
        private int m_ReceiveBufferSize = 10 * 10240;// buffer size to use for each socket I/O operation 
        //private const int c_OpsToPreAlloc = 2;    // read, write (don't alloc buffer space for accepts)
        /// <summary>
        /// 服务器端使用的Socket
        /// </summary>
        private Socket m_SvrSocket;            // the socket used to listen for incoming connection requests
        /// <summary>
        /// 接收数据的 SocketAsyncEventArgs
        /// </summary>
        private SocketAsyncEventArgs m_ReceiveSocketAsync;
        /// <summary>
        /// 限制可同时访问某一资源或资源池的线程数。
        /// </summary>
        private Semaphore m_MaxNumberAcceptedClients;
        /// <summary>
        /// 服务器的运行状态
        /// </summary>
        private bool m_IsRun = false;
        /// <summary>
        /// 超时时间(分钟)
        /// </summary>
        private int m_Timeouts = 10;
        /// <summary>
        /// 服务器程序监听的端口
        /// </summary>
        private int m_Port;
        /// <summary>
        /// 数据报文分析器
        /// </summary>
        private IResolver m_Resolver;
        /// <summary>
        /// 线程锁
        /// </summary>
        private ReaderWriterLock m_RWLS = new ReaderWriterLock();
        /// <summary>
        /// 保存所有客户端会话的表
        /// </summary>
        private Dictionary<EndPoint, Session> m_ClientSession = new Dictionary<EndPoint, Session>();
        /// <summary>
        /// 当前服务器运行开始共接收数据
        /// </summary>
        private Int64 m_TotalBytesRead;           // counter of the total # bytes received by the server
        /// <summary>
        /// 当前客户端链接数
        /// </summary>
        private int m_NumConnectedSockets;      // the total number of clients connected to the server 
        /// <summary>
        /// 清除离线车辆定时器
        /// </summary>
        private Timer m_Timer;
        /// <summary>
        /// 发送当前链接的客户端数量的计时器
        /// </summary>
        private Timer m_PromulgationEventTimer;
        /// <summary>
        /// 上一次链接的数据
        /// </summary>
        private int m_LastNumConnectedSockets;
        /// <summary>
        /// 上一次接收数据
        /// </summary>
        private Int64 m_LastTotalBytesRead;
        #endregion

        #region 属性
        /// <summary>
        /// 当前服务器是否运行
        /// </summary>
        public bool IsRunning
        {
            get { return m_IsRun; }
        }
        /// <summary>
        /// 当前服务器链接的客户端数量
        /// </summary>
        public int SessionCount
        {
            get { return m_ClientSession.Count; }
        }
        /// <summary>
        /// 客户端链接 Session
        /// </summary>
        public Dictionary<EndPoint, Session> ClientSession
        {
            get { return m_ClientSession; }
        }
        /// <summary>
        /// 系统使用的数据报文
        /// </summary>
        public IResolver Resolver
        {
            set { m_Resolver = value; }
            get { return m_Resolver; }
        }
        #endregion

        #region 事件
        ///// <summary>
        ///// 服务器已经满事件
        ///// </summary>
        //public event NetEventHandler ServerFull;
        /// <summary>
        /// 客户端建立连接事件
        /// </summary>
        public event NetEventHandler ClientConn;
        /// <summary>
        /// 客户端关闭事件
        /// </summary>
        public event NetEventHandler ClientClose;
        /// <summary>
        /// 服务器配置变更
        /// </summary>
        public event NetEventHandler ServerConfigChange;
        /// <summary>
        /// 信号接收完成 事件
        /// </summary>
        public event ReceiveDataEndEventHandler ReceiveDataEnd;
        /// <summary>
        /// 信号发送完成 事件
        /// </summary>
        public event SendDataEndEventHandler SendDataEnd;
        /// <summary>
        /// 连接客户端数量发送改变
        /// </summary>
        public event ClientConnectionChangeEventHandler ClientConnectionChange;
        /// <summary>
        /// 服务器接收的客户端字节总数
        /// </summary>
        public event ReceiveTotalBytesEventHandler ReceiveTotalBytes;
        #endregion

        #region 构造函数
        /// <summary>
        /// 构造函数(默认使用ASCII编码方式)
        /// </summary>
        /// <param name="port">服务器端监听的端口号</param>
        /// <param name="timeouts">链接超时时间(分钟)</param>
        /// <param name="resolver">报文解析器</param>
        public UDPServer(int port, int timeouts, IResolver resolver) : this(port, 50000, timeouts, resolver)
        { }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="port">服务器端监听的端口号</param>
        /// <param name="maxClient">服务器能容纳客户端的最大能力</param>
        /// <param name="timeouts">链接超时时间(分钟)</param>
        /// <param name="resolver">报文解析器</param>
        public UDPServer(int port, int maxClient, int timeouts, IResolver resolver)
        {
            m_Port = port;
            m_MaxConnectionsCount = maxClient;
            m_Timeouts = timeouts;
            // 定时清除离线Socket
            m_Timer = new System.Threading.Timer(ClearOffTerminal, null, 0, 30000);

            m_PromulgationEventTimer = new System.Threading.Timer(OnPromulgationEvent, null, 0, 1000);

            m_Resolver = resolver;
            m_MaxNumberAcceptedClients = new Semaphore(m_MaxConnectionsCount, m_MaxConnectionsCount);

            m_ReceiveSocketAsync = new SocketAsyncEventArgs();
            m_ReceiveSocketAsync.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed);
            m_ReceiveSocketAsync.SetBuffer(new byte[m_ReceiveBufferSize], 0, m_ReceiveBufferSize);

        }
        #endregion

        #region Socket方法
        /// <summary>
        /// 对外广播相关数据
        /// </summary>
        /// <param name="obj"></param>
        private void OnPromulgationEvent(object obj)
        {
            OnClientConnectionChange(obj);
            OnReceiveTotalBytes(obj);
        }
        /// <summary>
        /// 重新设置端口号,超时时间,报文解析器
        /// </summary>
        /// <param name="port">监听端口号</param>
        /// <param name="Timeouts">超时时间</param>
        /// <param name="resolver">报文解析器</param>
        public void SetSocketParameter(int port, int timeouts, IResolver resolver)
        {
            Stop();
            Thread.Sleep(1000);
            this.m_Port = port;
            this.m_Timeouts = timeouts;
            this.m_Resolver = resolver;
            OnServerConfigChange();
        }
        /// <summary>
        /// 开始监听指定端口
        /// </summary>
        public void Start()
        {
            if (m_IsRun)
            {
                return;
            }
            m_TotalBytesRead = 0L;
            IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, m_Port);
            m_SvrSocket = new Socket(localEndPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
            m_SvrSocket.Bind(localEndPoint);
            //m_SvrSocket.Listen(m_MaxConnectionsCount);
            m_ReceiveSocketAsync.UserToken = m_SvrSocket;
            m_ReceiveSocketAsync.RemoteEndPoint = localEndPoint;
            if (!m_SvrSocket.ReceiveFromAsync(m_ReceiveSocketAsync))
            {
                ProcessReceive(m_ReceiveSocketAsync);
            }
            m_IsRun = true;
        }
        /// <summary>
        /// 停止监听端口
        /// </summary>
        public void Stop()
        {
            if (m_IsRun)
            {
                if (m_SvrSocket.Connected)
                {
                    m_SvrSocket.Shutdown(SocketShutdown.Both);
                }
                //关闭所有的客户端
                CloseAllClient();
                //清理资源
                m_SvrSocket.Close();
                m_IsRun = false;
                //将保存的所有的客户端会话信息清空
            }
        }

        /// <summary>
        /// This method is called whenever a receive or send opreation is completed on a socket 
        /// </summary> 
        /// <param name="e">SocketAsyncEventArg associated with the completed receive operation</param>
        private void IO_Completed(object sender, SocketAsyncEventArgs e)
        {
            // determine which type of operation just completed and call the associated handler
            switch (e.LastOperation)
            {
                case SocketAsyncOperation.ReceiveFrom:
                    ProcessReceive(e);
                    break;
                //case SocketAsyncOperation.Send:
                //    ProcessSend(e);
                //    break;
                //default:
                //    throw new ArgumentException("The last operation completed on the socket was not a receive or send");
            }
        }
        /// <summary>
        ///  当一个异步接收操作完成时调用该方法。  
        ///  如果远程主机关闭了连接，该Socket也关闭。  
        ///  如果收到数据，则回返到客户端。 
        /// </summary>
        private void ProcessReceive(SocketAsyncEventArgs e)
        {
            // 检查远程主机是否关闭了连接。
            Socket userTokenSocket = e.UserToken as Socket;
            if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
            {
                //增加服务器接收的总字节数
                Interlocked.Add(ref m_TotalBytesRead, e.BytesTransferred);
                //Console.WriteLine("The server has read a total of {0} bytes", m_TotalBytesRead);
                //将接收到的数据暂存到Session中, 如果有相关数据,则进行拼接
                if (null != ReceiveDataEnd)
                {
                    Session sendDataSession = FindOrCreateSession(e.RemoteEndPoint);
                    if (null == sendDataSession)
                    {
                        Interlocked.Add(ref m_TotalBytesRead, -e.BytesTransferred);//无Session接收数据,故需要将服务器接收到的总字节减少
                        //收完数据后,进行下一次接收
                        userTokenSocket.ReceiveFromAsync(e);
                        return;
                    }
                    sendDataSession.LastConnectionTime = DateTime.Now;

                    byte[] receivedByte = new byte[e.BytesTransferred];
                    Array.Copy(e.Buffer, e.Offset, receivedByte, 0, e.BytesTransferred);

                    // 如果没有报文结束符标记,则直接进行数据转发
                    if (string.IsNullOrEmpty(m_Resolver.EndTag) && string.IsNullOrEmpty(m_Resolver.HexStringEndTag))
                    {
                        //深拷贝,为了保持Datagram的对立性
                        ICloneable copySession = (ICloneable)sendDataSession;
                        Session clientSession = (Session)copySession.Clone();
                        clientSession.DatagramByte = receivedByte;
                        clientSession.Datagram = this.m_Resolver.DatagramDesEncoding(receivedByte);
                        //发布一个报文消息
                        OnReceiveSignalEnd(this, new NetEventArgs(clientSession));
                    }
                    else //存在报文结束符,则需要进行分割
                    {
                        string receivedData = this.m_Resolver.ByteToHexString(receivedByte);

                        if (!string.IsNullOrEmpty(sendDataSession.SpareDatagram) && sendDataSession.SpareDatagram.Length != 0)
                        {
                            //加上最后一次通讯剩余的报文片断
                            receivedData = string.Concat(sendDataSession.SpareDatagram, ",", receivedData);
                        }
                        string[] recvDatagrams = m_Resolver.Resolve(ref receivedData);
                        //剩余的代码片断,下次接收的时候使用
                        sendDataSession.SpareDatagram = receivedData;
                        receivedData = null;
                        foreach (string newDatagram in recvDatagrams)
                        {
                            //深拷贝,为了保持Datagram的对立性
                            ICloneable copySession = (ICloneable)sendDataSession;
                            Session clientSession = (Session)copySession.Clone();
                            clientSession.DatagramByte = this.m_Resolver.HexStringToByte(newDatagram);
                            clientSession.Datagram = this.m_Resolver.DatagramDesEncoding(clientSession.DatagramByte);
                            //发布一个报文消息
                            OnReceiveSignalEnd(this, new NetEventArgs(clientSession));
                        }
                    } //end of if(ReceiveSignalEnd != null)
                }
                //收完数据后,进行下一次接收
                if (!userTokenSocket.ReceiveFromAsync(e))
                {
                    ProcessReceive(e);
                }
            }
            else
            {
                if (e.SocketError != SocketError.OperationAborted)
                {
                    try
                    {
                        CloseClientSocket(FindSession(((Socket)e.UserToken).RemoteEndPoint));
                    }
                    catch
                    {  }
                }
            }
        }
        /// <summary>
        /// 关闭所有的客户端会话,与所有的客户端连接会断开
        /// </summary>
        public void CloseAllClient()
        {
            List<Session> sessionList = new List<Session>();
            sessionList.AddRange(m_ClientSession.Values);
            while (sessionList.Count > 0)
            {
                CloseClientSocket(sessionList[0]);
                sessionList.Remove(sessionList[0]);
            }
        }
        /// <summary>
        /// 关闭指定Session客户端
        /// </summary>
        /// <param name="session"></param>
        public void CloseClientSocket(Session session)
        {
            if (null == session || null == session.ID)
            {
                return;
            }
            OnClientClose(this, new NetEventArgs(session));
            //m_RWLS.EnterWriteLock();
            m_RWLS.AcquireWriterLock(1000);
            try
            {
                if (m_ClientSession.ContainsKey(session.ID))
                {
                    session.Datagram = null;
                    session.DatagramByte = null;
                    m_ClientSession.Remove(session.ID);
                }
            }
            finally
            {
                m_RWLS.ReleaseWriterLock();
            }
            Interlocked.Decrement(ref m_NumConnectedSockets);
        }
        /// <summary>
        /// 关闭指定客户端
        /// </summary>
        /// <param name="endPoint"></param>
        public void CloseClientSocket(EndPoint endPoint)
        {
            CloseClientSocket(FindSession(endPoint));
        }
        /// <summary>
        /// 查找或创建Session对象
        /// 如果未查找到对应的Session对象,则创建一个新的Session返回,
        /// 并将新创建的对象存入 ClientSession对象中
        /// </summary>
        /// <param name="cliSock"></param>
        /// <returns></returns>
        private Session FindOrCreateSession(EndPoint endPoint)
        {
            if (null == endPoint)
            {
                return null;
            }
            m_RWLS.AcquireWriterLock(1000);
            try
            {
                Session session;
                if (this.m_ClientSession.TryGetValue(endPoint, out session))
                {
                    return session;
                }
                else
                {
                    if (m_NumConnectedSockets > m_MaxConnectionsCount)
                    {
                        //超过最大链接数
                        return null;
                    }
                    session = new Session(endPoint, m_Timeouts);
                    m_ClientSession.Add(endPoint, session);
                    Interlocked.Increment(ref m_NumConnectedSockets);
                    OnClientConn(this, new NetEventArgs(session));
                    return session;
                }
            }
            catch (Exception ex)
            {
                return null;
            }
            finally
            {
                if (m_RWLS.IsWriterLockHeld)
                {
                    m_RWLS.ReleaseWriterLock();
                }
            }
        }
        /// <summary>
        /// 查找或创建Session对象
        /// 如果未查找到对应的Session对象,则创建一个新的Session返回,
        /// 并将新创建的对象存入 ClientSession对象中
        /// </summary>
        /// <param name="cliSock"></param>
        /// <returns></returns>
        private Session FindSession(EndPoint endPoint)
        {
            if (null == endPoint)
            {
                return null;
            }
            m_RWLS.AcquireReaderLock(1000);
            try
            {
                Session session;
                if (this.m_ClientSession.TryGetValue(endPoint, out session))
                {
                    return session;
                }
                return null;
            }
            finally
            {
                m_RWLS.ReleaseReaderLock();
            }
        }
        /// <summary>
        /// 服务器端发送数据的方法
        /// 如有设置报文结束符,则会添加报文结束符
        /// </summary>
        /// <param name="endPoint">数据的IP地址</param>
        /// <param name="datagram">需发送的报文数据(不包含报文结束符)</param>
        /// <param name="isCloseSession">发送完成后进行断开链接</param>
        public virtual void AsyncSend(EndPoint endPoint, string datagram, bool isAddEndTag = true)
        {
            byte[] bt = this.m_Resolver.DatagramEncodingBarringEngTag(datagram);
            AsyncSend(endPoint, bt, isAddEndTag);
        }
        /// <summary>
        /// 服务器端发送数据的方法
        /// </summary>
        /// <param name="recvDataClient">接收数据的客户端会话（特定的客户）</param>
        /// <param name="datagram">需发送的报文数据(不包含报文结束符)</param>
        /// <param name="isAddEndTag">是否自动添加结束符</param>
        /// <param name="isCloseSession">发送完成后进行断开链接</param>
        public virtual void AsyncSend(Session recvDataClient, string datagram, bool isAddEndTag = true)
        {
            byte[] bt = this.m_Resolver.DatagramEncodingBarringEngTag(datagram);
            AsyncSend(recvDataClient.ClientSocketAsyncEventArgs.RemoteEndPoint, bt, isAddEndTag);
        }
        /// <summary>
        /// 服务器端发送数据的方法
        /// </summary>
        /// <param name="recvDataClient">接收数据的客户端会话（特定的客户）</param>
        /// <param name="bt">数据报文(不包含报文结束符)</param>
        /// <param name="isAddEndTag">是否自动添加结束符</param>
        /// <param name="isCloseSession">发送完成后进行断开链接</param>
        public virtual void AsyncSend(EndPoint endPoint, byte[] bt, bool isAddEndTag = true)
        {
            if (isAddEndTag)
            {
                bt = this.m_Resolver.DatagramAddEndTag(bt);
            }
            m_SvrSocket.BeginSendTo( bt,
                                0,
                                bt.Length,
                                SocketFlags.None,
                                endPoint,
                                new AsyncCallback(AsyncEndSend),
                                m_SvrSocket);
        }
        /// <summary>
        /// 发送数据完成
        /// </summary>
        /// <param name="iar"></param>
        private void AsyncEndSend(IAsyncResult iar)
        {
            Socket client = (Socket)iar.AsyncState;
            if (m_IsRun)
            {
                try
                {
                    client.EndSendTo(iar);
                    OnSendCommandEnd(this, new SendStateEventArgs(SendState.Success));
                }
                catch (SocketException se)
                { }
            }
        }
        /// <summary>
        /// 发送数据完毕
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void ClientSendSocketAsyncEventArgs_Completed(object sender, SocketAsyncEventArgs e)
        {
            switch (e.LastOperation)
            {
                case SocketAsyncOperation.Send:
                    {
                        if (e.SocketError == SocketError.Success)
                        {
                            OnSendCommandEnd(this, new SendStateEventArgs(SendState.Success));
                        }
                        else
                        {
                            OnSendCommandEnd(this, new SendStateEventArgs(SendState.Failure));
                        }
                        e.Completed -= new EventHandler<SocketAsyncEventArgs>(ClientSendSocketAsyncEventArgs_Completed);
                    }
                    break;
            }
        }
        /// <summary>
        /// 发送数据完毕后 关闭与客户端的链接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void ClientSendSocketAsyncEventArgs_Completed_Close(object sender, SocketAsyncEventArgs e)
        {
            switch (e.LastOperation)
            {
                case SocketAsyncOperation.Send:
                    {
                        if (e.SocketError == SocketError.Success)
                        {
                            OnSendCommandEnd(this, new SendStateEventArgs(SendState.Success));
                        }
                        else
                        {
                            OnSendCommandEnd(this, new SendStateEventArgs(SendState.Failure));
                        }
                        e.Completed -= new EventHandler<SocketAsyncEventArgs>(ClientSendSocketAsyncEventArgs_Completed_Close);
                        CloseClientSocket(((Socket)e.UserToken).RemoteEndPoint);
                    }
                    break;
            }
        }
        /// <summary>
        /// 发送数据完成处理函数,并断开与客户端的链接
        /// </summary>
        /// <param name="iar">目标客户端Socket</param>
        protected virtual void SendDataEndAndCloseSessionAsyncResult(IAsyncResult iar)
        {
            try
            {
                SocketAsyncEventArgs args = (SocketAsyncEventArgs)iar.AsyncState;
                Socket client = args.UserToken as Socket;
                client.EndSend(iar);
                OnSendCommandEnd(this, new SendStateEventArgs(SendState.Success));
                Thread.Sleep(500);//休眠 500 毫秒, 防止数据缓冲区还未发送完
                try
                {
                    CloseClientSocket(FindSession(client.RemoteEndPoint));
                }
                catch 
                { }
            }
            catch
            {
                OnSendCommandEnd(this, new SendStateEventArgs(SendState.Failure));
            }
        }
        /// <summary>
        /// 发送数据完成处理函数
        /// </summary>
        /// <param name="iar">目标客户端Socket</param>
        protected virtual void SendDataEndAsyncResult(IAsyncResult iar)
        {
            SocketAsyncEventArgs args = (SocketAsyncEventArgs)iar.AsyncState;
            Socket client = args.UserToken as Socket;
            try
            {
                int sent = client.EndSend(iar);
                OnSendCommandEnd(this, new SendStateEventArgs(SendState.Success));
            }
            catch
            {
                OnSendCommandEnd(this, new SendStateEventArgs(SendState.Failure));
                try
                {
                    CloseClientSocket(FindSession(client.RemoteEndPoint));
                }
                catch
                { }
            }
        }
        /// <summary>
        /// 清除已经离线设备
        /// </summary>
        /// <param name="obj"></param>
        private void ClearOffTerminal(object obj)
        {
            if (null != this.m_ClientSession && this.m_ClientSession.Count > 0 && this.m_Timeouts > 0)
            {
                try
                {
                    List<EndPoint> list = new List<EndPoint>();
                    IPEndPoint[] tmpIpept = new IPEndPoint[this.m_ClientSession.Keys.Count];
                    this.m_ClientSession.Keys.CopyTo(tmpIpept, 0);
                    foreach (EndPoint id in tmpIpept)
                    {
                        Session session = null;
                        if (null != id && this.m_ClientSession.TryGetValue(id, out session))
                        {
                            if ((DateTime.Now - session.LastConnectionTime) > session.Timeouts)
                            {
                                list.Add(id);
                            }
                        }
                    }
                    foreach (EndPoint id in list)
                    {
                        Session session = null;
                        if (this.m_ClientSession.TryGetValue(id, out session))
                        {
                            CloseClientSocket(session);
                        }
                    }
                }
                catch
                { }
            }
        }
        #endregion

        #region 事件触发
        /// <summary>
        /// 数据报文发送完成
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnSendCommandEnd(object sender, SendStateEventArgs e)
        {
            if (SendDataEnd != null)
            {
                Delegate[] delegateList = SendDataEnd.GetInvocationList();
                foreach (SendDataEndEventHandler handler in delegateList)
                {
                    handler.BeginInvoke(sender, e, null, null);
                }
            }
        }
        /// <summary>
        /// 新的客户端连接,发出通知
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnClientConn(object sender, NetEventArgs e)
        {
            if (ClientConn != null)
            {
                Delegate[] delegateList = ClientConn.GetInvocationList();
                foreach (NetEventHandler handler in delegateList)
                {
                    handler.BeginInvoke(sender, e, null, null);
                }
            }
        }
        /// <summary>
        /// Client 断开连接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnClientClose(object sender, NetEventArgs e)
        {
            if (null != ClientClose)
            {
                Delegate[] delegateList =ClientClose.GetInvocationList();
                foreach (NetEventHandler handler in delegateList)
                {
                    handler.BeginInvoke(sender, e, null, null);
                }
            }
        }
        /// <summary>
        /// 信号接收完成 事件,通知相关订阅者
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnReceiveSignalEnd(object sender, NetEventArgs e)
        {
            if (null != ReceiveDataEnd)
            {
                Delegate[] delegateList = ReceiveDataEnd.GetInvocationList();
                foreach (ReceiveDataEndEventHandler handler in delegateList)
                {
                    handler.BeginInvoke(sender, e, null, null);
                }
            }
        }
        /// <summary>
        /// 配置变更
        /// </summary>
        private void OnServerConfigChange()
        {
            if (null != ServerConfigChange)
            {
                Delegate[] delegateList = ServerConfigChange.GetInvocationList();
                foreach (NetEventHandler handler in delegateList)
                {
                    handler.BeginInvoke(this, null, null, null);
                }
            }
        }
        /// <summary>
        /// Client 连接发送改变
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnClientConnectionChange(object sender)
        {
            if (m_LastNumConnectedSockets != m_NumConnectedSockets)
            {
                m_LastNumConnectedSockets = m_NumConnectedSockets;
            }
            else
            {   //数据没改变,不进行发送
                return;
            }
            if (null != ClientConnectionChange)
            {
                ConnectCountEventArgs e = new ConnectCountEventArgs(m_NumConnectedSockets);
                Delegate[] delegateList = ClientConnectionChange.GetInvocationList();
                foreach (ClientConnectionChangeEventHandler handler in delegateList)
                {
                    handler.BeginInvoke(sender, e, null, null);
                }
            }
        }        
         /// <summary>
        /// 服务器接收字节总数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnReceiveTotalBytes(object sender)
        {
            if (m_LastTotalBytesRead != m_TotalBytesRead)
            {
                m_LastTotalBytesRead = m_TotalBytesRead;
            }
            else
            {   //数据没改变,不进行发送
                return;
            }
            if (null != ReceiveTotalBytes)
            {
                ReceiveTotalBytesEventArgs e = new ReceiveTotalBytesEventArgs(m_TotalBytesRead);
                Delegate[] delegateList = ReceiveTotalBytes.GetInvocationList();
                foreach (ReceiveTotalBytesEventHandler handler in delegateList)
                {
                    handler.BeginInvoke(sender, e, null, null);
                }
            }
        }
        #endregion
    }
}
